package com.ruoyi.system.controller;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.system.domain.InvoiceDetail;
import com.ruoyi.system.domain.InvoiceWare;
import com.ruoyi.system.domain.VendorInvoicing;
import com.ruoyi.system.service.*;
import com.ruoyi.system.service.impl.VendorInvoicingServiceImpl;
import com.ruoyi.system.util.DateUtil;
import com.ruoyi.system.util.SnowflakeIDGenerator;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.InvoiceFlow;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 供应商流水Controller
 * 
 * @author ruoyi
 * @date 2024-06-18
 */
@RestController
@RequestMapping("/system/flow")
public class InvoiceFlowController extends BaseController
{
    @Autowired
    private IInvoiceFlowService invoiceFlowService;
    @Autowired
    private IInvoiceRecordsService invoiceRecordsService;
    @Autowired
    private IProvideRecordsService provideRecordsService;
    @Autowired
    private IVendorInvoicingService vendorInvoicingService;
    @Autowired
    private IInvoiceDetailService invoiceDetailService;
    @Autowired
    private IInvoiceWareService invoiceWareService;

    /**
     * 查询供应商流水列表
     */
    @GetMapping("/list")
    public TableDataInfo list(InvoiceFlow invoiceFlow)
    {
        startPage();
        List<InvoiceFlow> list = invoiceFlowService.selectInvoiceFlowList(invoiceFlow);
        return getDataTable(list);
    }

    /**
     * 导出供应商流水列表
     */
    @Log(title = "供应商流水", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, InvoiceFlow invoiceFlow)
    {
        List<InvoiceFlow> list = invoiceFlowService.selectInvoiceFlowList(invoiceFlow);
        ExcelUtil<InvoiceFlow> util = new ExcelUtil<InvoiceFlow>(InvoiceFlow.class);
        util.exportExcel(response, list, "供应商流水数据");
    }

    /**
     * 获取供应商流水详细信息
     */
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(invoiceFlowService.selectInvoiceFlowById(id));
    }

    /**
     * 新增供应商流水
     */
    @Log(title = "供应商流水", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody InvoiceFlow invoiceFlow)
    {
        return toAjax(invoiceFlowService.insertInvoiceFlow(invoiceFlow));
    }

    /**
     * 修改供应商流水
     */
    @Log(title = "供应商流水", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody InvoiceFlow invoiceFlow)
    {
        return toAjax(invoiceFlowService.updateInvoiceFlow(invoiceFlow));
    }

    /**
     * 删除供应商流水
     */
    @Log(title = "供应商流水", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(invoiceFlowService.deleteInvoiceFlowByIds(ids));
    }


    /**
     * 添加中心库开票数据
     */
    @Transactional
    @GetMapping("/insertByInvoice")
    public AjaxResult insertByInvoice(@RequestParam(value = "startTime",required = false)String startTime,
                                      @RequestParam(value="provide",required = false)String provide) throws ParseException {
        InvoiceWare invoiceWare = new InvoiceWare();
        invoiceWare.setProvideWare("中心库");
        invoiceWare.setTime(startTime);
        List<InvoiceWare> invoiceWares = invoiceWareService.selectInvoiceWareList(invoiceWare);
        if(invoiceWares!=null&&invoiceWares.size()>0){
            invoiceWares.get(0).setStatus("1");
            invoiceWareService.updateInvoiceWare(invoiceWares.get(0));
        }else {
            invoiceWare.setStatus("1");
            invoiceWareService.insertInvoiceWare(invoiceWare);
        }
        DecimalFormat df = new DecimalFormat("0.00##");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> provideList = invoiceRecordsService.listProvide(provide);
        for (String provideStr:provideList) {
            List<Map<String, Object>> maps = invoiceFlowService.listInvoiceMoney(provideStr, startTime);
            for (Map<String,Object> map:maps) {
                String money = df.format(map.get("money"));
                String productGroup = (String) map.get("product_group");
                String company = (String)map.get("company");
                VendorInvoicing vendorInvoicing = new VendorInvoicing();
                vendorInvoicing.setProvide(provideStr);
                vendorInvoicing.setProductGroup(productGroup);
                vendorInvoicing.setProductWare("中心库");
                vendorInvoicing.setCompany(company);
                VendorInvoicing vendorInvoicing1 = vendorInvoicingService.getVendorInvoicing(vendorInvoicing);
                int count = 0;
                //对比是否有结存记录
                if(vendorInvoicing1!=null){
                    vendorInvoicing1.setMoeny(df.format(Double.valueOf(money)+Double.valueOf(vendorInvoicing1.getMoeny())));
                 count =   vendorInvoicingService.updateVendorInvoicing(vendorInvoicing1);
                }else{
                    vendorInvoicing.setMoeny(money);
                 count = vendorInvoicingService.insertVendorInvoicing(vendorInvoicing);
                }
                if(count>0){
                    //储存流水表
                    InvoiceFlow invoiceFlow = new InvoiceFlow();
                    invoiceFlow.setInvoiceTime(sdf.format(new Date()));
                    invoiceFlow.setProvideGroup(productGroup);
                    invoiceFlow.setProvideMoney(money);
                    invoiceFlow.setProvideWare("中心库");
                    invoiceFlow.setCompany(company);
                    //判断是否之前有开票流水
                    InvoiceFlow invoiceFlow1 = invoiceFlowService.listLastInvoiceFlow(provideStr);
                    if(invoiceFlow1!=null){
                         Double balanceMoney = Double.valueOf(invoiceFlow1.getBalanceMoney());
                         Double doubleMoney = Double.valueOf(money);
                        invoiceFlow.setBalanceMoney(df.format(balanceMoney+doubleMoney));
                    }else{
                        invoiceFlow.setBalanceMoney(money);
                    }
                    invoiceFlow.setProvideType("入账");
                    invoiceFlow.setRemark("中心库"+startTime+"("+productGroup+")入账");
                    invoiceFlow.setProvide(provideStr);
                    invoiceFlowService.insertInvoiceFlow(invoiceFlow);

                    //储存开票明细表
                    InvoiceDetail invoiceDetail = new InvoiceDetail();
                    invoiceDetail.setProvide(provideStr);
                    invoiceDetail.setProvideMoney(money);
                    invoiceDetail.setProvideGroup(productGroup);
                    invoiceDetail.setProvideType("入账");
                    invoiceDetail.setRemark("中心库"+startTime+"("+productGroup+")入账");
                    invoiceDetail.setInvoiceTime(sdf.format(new Date()));
                    invoiceDetail.setProvideWare("中心库");
                    invoiceDetail.setBalanceMoney(money);
                    invoiceDetail.setCompany(company);
                    invoiceDetailService.insertInvoiceDetail(invoiceDetail);
                }
            }
            }
        List<InvoiceWare> invoiceWares1 = invoiceWareService.selectInvoiceWareList(invoiceWare);
        if(invoiceWares1!=null&&invoiceWares1.size()>0){
            invoiceWares1.get(0).setStatus("2");
            invoiceWareService.updateInvoiceWare(invoiceWares1.get(0));
        }
        return AjaxResult.success("入账成功");
    }

    /**
     * 添加配件库开票数据
     */
    @Transactional
    @GetMapping("/insertByProvideRevords")
    public AjaxResult insertByProvideRevords(@RequestParam(value = "startTime",required = false)String startTime,
                                      @RequestParam(value="provide",required = false)String provide) throws ParseException {
        InvoiceWare invoiceWare = new InvoiceWare();
        invoiceWare.setProvideWare("配件库");
        invoiceWare.setTime(startTime);
        List<InvoiceWare> invoiceWares = invoiceWareService.selectInvoiceWareList(invoiceWare);
        if(invoiceWares!=null&&invoiceWares.size()>0){
            invoiceWares.get(0).setStatus("1");
            invoiceWareService.updateInvoiceWare(invoiceWares.get(0));
        }else {
            invoiceWare.setStatus("1");
            invoiceWareService.insertInvoiceWare(invoiceWare);
        }
        DecimalFormat df = new DecimalFormat("0.00##");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<String> provideList = provideRecordsService.selectProvideList(provide);
        for (String provideStr:provideList) {
            List<Map<String, Object>> maps = invoiceFlowService.listProvideMoney(provideStr, startTime);
            for (Map<String,Object> map:maps) {
                String money = df.format(map.get("money"));
                String productGroup = (String) map.get("product_group");
                VendorInvoicing vendorInvoicing = new VendorInvoicing();
                vendorInvoicing.setProvide(provideStr);
                vendorInvoicing.setProductGroup(productGroup);
                vendorInvoicing.setProductWare("配件库");
                VendorInvoicing vendorInvoicing1 = vendorInvoicingService.getVendorInvoicing(vendorInvoicing);
                int count = 0;
                //对比是否有结存记录
                if(vendorInvoicing1!=null){
                    vendorInvoicing1.setMoeny(df.format(Double.valueOf(money)+Double.valueOf(vendorInvoicing1.getMoeny())));
                    count =   vendorInvoicingService.updateVendorInvoicing(vendorInvoicing1);
                }else{
                    vendorInvoicing.setMoeny(money);
                    count = vendorInvoicingService.insertVendorInvoicing(vendorInvoicing);
                }
                if(count>0){
                    //储存流水表
                    InvoiceFlow invoiceFlow = new InvoiceFlow();
                    invoiceFlow.setInvoiceTime(sdf.format(new Date()));
                    invoiceFlow.setProvideGroup(productGroup);
                    invoiceFlow.setProvideWare("配件库");
                    invoiceFlow.setProvideMoney(money);
                    //判断是否之前有开票流水
                    InvoiceFlow invoiceFlow1 = invoiceFlowService.listLastInvoiceFlow(provideStr);
                    if(invoiceFlow1!=null){
                        Double balanceMoney = Double.valueOf(invoiceFlow1.getBalanceMoney());
                        Double doubleMoney = Double.valueOf(money);
                        invoiceFlow.setBalanceMoney(df.format(balanceMoney+doubleMoney));
                    }else{
                        invoiceFlow.setBalanceMoney(money);
                    }
                    invoiceFlow.setProvideType("入账");
                    invoiceFlow.setRemark("配件库"+startTime+"("+productGroup+")入账");
                    invoiceFlow.setProvide(provideStr);
                    invoiceFlowService.insertInvoiceFlow(invoiceFlow);

                    //储存开票明细表
                    InvoiceDetail invoiceDetail = new InvoiceDetail();
                    invoiceDetail.setProvide(provideStr);
                    invoiceDetail.setProvideMoney(money);
                    invoiceDetail.setProvideGroup(productGroup);
                    invoiceDetail.setProvideType("入账");
                    invoiceDetail.setRemark("配件库"+startTime+"("+productGroup+")入账");
                    invoiceDetail.setInvoiceTime(sdf.format(new Date()));
                    invoiceDetail.setProvideWare("配件库");
                    invoiceDetail.setBalanceMoney(money);
                    invoiceDetailService.insertInvoiceDetail(invoiceDetail);
                }
            }
        }
        List<InvoiceWare> invoiceWares1 = invoiceWareService.selectInvoiceWareList(invoiceWare);
        if(invoiceWares1!=null&&invoiceWares1.size()>0){
            invoiceWares1.get(0).setStatus("2");
            invoiceWareService.updateInvoiceWare(invoiceWares1.get(0));
        }
        return AjaxResult.success("入账成功");
    }

    /**
     * 检查开票
     */
    @GetMapping("/checkInvoicing")
    public AjaxResult checkInvoicing(@RequestParam(value = "id",required = false)Long id,
                                @RequestParam(value = "uuid",required = true)String uuid) throws ParseException {
        VendorInvoicing vendorInvoicing = new VendorInvoicing();
        vendorInvoicing.setId(id);
        vendorInvoicing.setUuid(uuid);
        VendorInvoicing vendorInvoicing1 = vendorInvoicingService.getVendorInvoicing(vendorInvoicing);
        if(vendorInvoicing1==null){
            return AjaxResult.error(4001,"对不起 您要修改的数据已变更 请重新刷新页面获取最新数据！");
        }
        return AjaxResult.success("检查成功!");
    }


    /**
     * 开票
     */
    @GetMapping("/invoicing")
    public AjaxResult invoicing(@RequestParam(value = "money",required = false)String money,
                                             @RequestParam(value="productGroup",required = false)String productGroup,
                                @RequestParam(value = "provide",required = false)String provide,
                                @RequestParam(value = "remark",required = false)String remark,
                                @RequestParam(value = "productWare",required = false)String productWare,
                                @RequestParam(value = "company",required=false)String company,
                                @RequestParam(value = "uuid",required = true)String uuid) throws ParseException {
        DecimalFormat df = new DecimalFormat("0.00##");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            VendorInvoicing vendorInvoicing = new VendorInvoicing();
            vendorInvoicing.setProvide(provide);
            vendorInvoicing.setProductWare(productWare);
            vendorInvoicing.setProductGroup(productGroup);
            vendorInvoicing.setUuid(uuid);
            if(company!=null&&company!=""){
                vendorInvoicing.setCompany(company);
            }
            VendorInvoicing vendorInvoicing1 = vendorInvoicingService.getVendorInvoicing(vendorInvoicing);
            if(vendorInvoicing1==null){
                return AjaxResult.error(4001,"对不起 您要修改的数据已变更 请重新刷新页面获取最新数据！");
            }
            if(Double.valueOf(money)>Double.valueOf(vendorInvoicing1.getMoeny())){
                return AjaxResult.success("对不起 开票金额不能大于结存金额！");
            }else{
                vendorInvoicing1.setMoeny(df.format(Double.valueOf(vendorInvoicing1.getMoeny())-Double.valueOf(money)));

                //开票的时候修改uuid
                SnowflakeIDGenerator snowflakeIDGenerator = new SnowflakeIDGenerator(1);
                long newUUid = snowflakeIDGenerator.nextId();
                vendorInvoicing1.setUuid(String.valueOf(newUUid));

                int count = vendorInvoicingService.updateVendorInvoicing(vendorInvoicing1);
                if(count>0){
                    InvoiceFlow invoiceFlow = new InvoiceFlow();
                    invoiceFlow.setInvoiceTime(sdf.format(new Date()));
                    invoiceFlow.setProvideGroup(productGroup);
                    invoiceFlow.setProvideMoney("-"+money);
                    if(company!=null&&company!=""){
                        invoiceFlow.setCompany(company);
                    }
                    //判断是否之前有开票流水
                    InvoiceFlow invoiceFlow1 = invoiceFlowService.listLastInvoiceFlow(provide);
                    if(invoiceFlow1!=null){
                        Double balanceMoney = Double.valueOf(invoiceFlow1.getBalanceMoney());
                        Double doubleMoney = Double.valueOf(money);
                        invoiceFlow.setBalanceMoney(df.format(balanceMoney-doubleMoney));
                    }else{
                        return   AjaxResult.success("对不起 没有入账的数据 无法记录流水！");
                    }
                    invoiceFlow.setProvideGroup(productGroup);
                    invoiceFlow.setProvideWare(productWare);
                    invoiceFlow.setRemark(remark);
                    invoiceFlow.setProvide(provide);
                    invoiceFlow.setProvideType("开票");
                    invoiceFlowService.insertInvoiceFlow(invoiceFlow);


                    //储存开票明细表
                    InvoiceDetail invoiceDetail = new InvoiceDetail();
                    invoiceDetail.setProvide(provide);
                    invoiceDetail.setProvideMoney("-"+money);
                    invoiceDetail.setProvideGroup(productGroup);
                    invoiceDetail.setProvideType("开票");
                    invoiceDetail.setRemark(remark);
                    invoiceDetail.setInvoiceTime(sdf.format(new Date()));
                    invoiceDetail.setProvideWare(productWare);
                    invoiceDetail.setBalanceMoney(vendorInvoicing1.getMoeny());
                    if(company!=null&&company!=""){
                        invoiceDetail.setCompany(company);
                    }
                    invoiceDetailService.insertInvoiceDetail(invoiceDetail);

                }
            }
        return AjaxResult.success("开票成功!");
    }

    /**
     * 发票红冲
     */
    @GetMapping("/invoiceBack")
    public AjaxResult invoiceBack(@RequestParam(value = "money",required = false)String money,
                                @RequestParam(value="productGroup",required = false)String productGroup,
                                @RequestParam(value = "provide",required = false)String provide,
                                @RequestParam(value = "remark",required = false)String remark,
                                @RequestParam(value = "productWare",required = false)String productWare,
                                  @RequestParam(value = "company",required = false)String company,
                                  @RequestParam(value = "id")Long id) throws ParseException {
        DecimalFormat df = new DecimalFormat("0.00##");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        VendorInvoicing vendorInvoicing = new VendorInvoicing();
        vendorInvoicing.setProvide(provide);
        vendorInvoicing.setProductWare(productWare);
        vendorInvoicing.setProductGroup(productGroup);
        vendorInvoicing.setCompany(company);
        VendorInvoicing vendorInvoicing1 = vendorInvoicingService.getVendorInvoicing(vendorInvoicing);
            vendorInvoicing1.setMoeny(df.format(Double.valueOf(vendorInvoicing1.getMoeny())+Double.valueOf(money)));
            int count = vendorInvoicingService.updateVendorInvoicing(vendorInvoicing1);
            if(count>0){
                InvoiceFlow invoiceFlow = new InvoiceFlow();
                invoiceFlow.setInvoiceTime(sdf.format(new Date()));
                invoiceFlow.setProvideGroup(productGroup);
                invoiceFlow.setProvideMoney(money);
                invoiceFlow.setCompany(company);
                //判断是否之前有开票流水
                InvoiceFlow invoiceFlow1 = invoiceFlowService.listLastInvoiceFlow(provide);
                if(invoiceFlow1!=null){
                    Double balanceMoney = Double.valueOf(invoiceFlow1.getBalanceMoney());
                    Double doubleMoney = Double.valueOf(money);
                    invoiceFlow.setBalanceMoney(df.format(balanceMoney+doubleMoney));
                }else{
                    return   AjaxResult.success("对不起 没有入账的数据 无法记录流水");
                }
                //修改当前记录为已作废
                InvoiceDetail invoiceDetail1 = invoiceDetailService.selectInvoiceDetailById(id);
                if(invoiceDetail1!=null){
                    invoiceDetail1.setStatus("1");
                    invoiceDetailService.updateInvoiceDetail(invoiceDetail1);
                }

                //储存流水表
                invoiceFlow.setProvideGroup(productGroup);
                invoiceFlow.setProvideWare(productWare);
                invoiceFlow.setRemark(remark);
                invoiceFlow.setProvide(provide);
                invoiceFlow.setProvideType("作废");
                invoiceFlow.setCompany(company);
                invoiceFlowService.insertInvoiceFlow(invoiceFlow);


                //储存开票明细表
                InvoiceDetail invoiceDetail = new InvoiceDetail();
                invoiceDetail.setProvide(provide);
                invoiceDetail.setProvideMoney(money);
                invoiceDetail.setProvideGroup(productGroup);
                invoiceDetail.setProvideType("作废");
                invoiceDetail.setRemark(remark);
                invoiceDetail.setInvoiceTime(sdf.format(new Date()));
                invoiceDetail.setProvideWare(productWare);
                invoiceDetail.setBalanceMoney(vendorInvoicing1.getMoeny());
                invoiceDetail.setCompany(company);
                invoiceDetailService.insertInvoiceDetail(invoiceDetail);

            }
        return AjaxResult.success("作废发票成功!");
    }

}
